package gouhuo.allbugs.top.job;

import com.google.gson.Gson;
import gouhuo.allbugs.top.model.domain.Chat;
import gouhuo.allbugs.top.service.ChatService;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;

import static gouhuo.allbugs.top.constant.RedisConstants.CHAT_LIST_KEY;

/**
 * 缓存预热任务 ，开发时可用在 test 里代替
 */
@Component
public class PreCacheJob {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private ChatService chatService;

    private final ExecutorService executorService =
            new ThreadPoolExecutor(40, 1000, 10000, TimeUnit.MINUTES,
                    new ArrayBlockingQueue<>(10000));

    // cron   日期格式:秒 分 时 日 月 年
    @Scheduled(cron = "0 55 23 * * *")
    public void doCacheRecommendUser() {
        Gson gson = new Gson();
        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        LocalDate date = LocalDate.now();
        String now = ":" + date.getYear() + "-" + date.getMonthValue();
        Set<String> keys = stringRedisTemplate.keys(CHAT_LIST_KEY + now + ":*");
        if (keys != null) {
            for (String key : keys) {
                List<Chat> userChatList = new ArrayList<>();
                List<String> redisList = opsForList.range(key, 0, -1);
                if (redisList != null && !redisList.isEmpty()) {
                    redisList.forEach(redis -> userChatList.add(gson.fromJson(redis, Chat.class)));
                }
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
//                    System.out.println("threadNameOne: " + Thread.currentThread().getName());
                    chatService.saveBatch(userChatList);
                }, executorService);
                futureList.add(future);
            }
            CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
            stopWatch.stop();
            //传统批处理:1375ms 线程池:1945ms
//            System.out.println(stopWatch.getTotalTimeMillis() + "ms");
        }
    }
}
